﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChainAnalises.Classes.DivizionToAccords;
using ChainAnalises.Classes.IntervalAnalysis;
using ChainAnalises.Classes.IntervalAnalysis.Characteristics;
using ChainAnalises.Classes.Project_A;

namespace Segmentator.Dividers
{
    /// <summary>
    /// Расчет основных характеристик просегментированной цепи
    /// </summary>
    class CalculatorResults
    {
        public Chain Chain { get; set; }
        public Chain SlotChain { get; set; }
        public AlphabetChain Alphabet { get;  set; }
        public double Threshold;

        public CalculatorResults(Chain chain,Chain slotChain, AlphabetChain alphabetChain, double  threshold)
        {
            Chain = chain;
            SlotChain = slotChain;
            Alphabet = alphabetChain;
            Threshold = threshold;
        }
        
        /// <summary>
        /// Возвращает энтропию  цепи
        /// </summary>
        /// <param name="linkUp">Привязка к месту в цепи</param>
        /// <returns></returns>
        public double GetEntropy(LinkUp linkUp, Chain chain)
        {
            return chain.GetCharacteristic(linkUp, CharacteristicsFactory.H);
        }
        /// <summary>
        /// Возвращает количество информации  цепи
        /// </summary>
        /// <param name="linkUp">Привязка к месту в цепи</param>
        /// <returns></returns>
        public double GetAmountOfInformation(LinkUp linkUp, Chain chain)
        {
            return chain.GetCharacteristic(linkUp, CharacteristicsFactory.Length) * GetEntropy(linkUp, chain);
        }

        /// <summary>
        /// Возвращает удалённость  цепи
        /// </summary>
        /// <param name="linkUp">Привязка к месту в цепи</param>
        /// <returns></returns>
        public double GetChainRemoteness(LinkUp linkUp, Chain chain)
        {
            return chain.GetCharacteristic(linkUp, CharacteristicsFactory.g);   
        }

        /// <summary>
        /// Возвращает регулярность цепи
        /// </summary>
        /// <param name="linkUp"></param>
        /// <returns></returns>
        public double GetChainRegularity(LinkUp linkUp, Chain chain)
        {
            return chain.GetCharacteristic(linkUp, CharacteristicsFactory.r);
        }

        /// <summary>
        /// Возвращает глубину цепи
        /// </summary>
        /// <param name="linkUp"></param>
        /// <returns></returns>
        public double GetChainGamut(LinkUp linkUp, Chain chain)
        {
            return SlotChain.GetCharacteristic(linkUp, CharacteristicsFactory.G);  
        }

        /// <summary>
        /// Возвращает теоритический объем словаря
        /// </summary>
        /// <returns></returns>
        public double GetTheoryVolumeOfAlphabet()
        {
            double one = 0;
            double f = 0;
            foreach (Chain element in Alphabet)
            {
                one = one + Calculator.frequency(SlotChain, element);
                if (Calculator.frequency(SlotChain, element) > f) f = Calculator.frequency(SlotChain, element);
            }
            double z = SlotChain.Length;
            double k = 1/(Math.Log(f * z));
            double b = k/f - 1;
            double v = k*z-b;

            return v;
        }

        /// <summary>
        /// Возвращает эмпирический объем словаря
        /// </summary>
        /// <returns></returns>
        public double GetEmpiricalVolumeOfAlphabet()
        {
            return Alphabet.power;
        }

        /// <summary>
        /// Возвращает строй исходной цепи
        /// </summary>
        /// <returns></returns>
        public string GetFormationChain()
        {
            return ConvertArray.ArrayToString(Chain.Building);
        }

        /// <summary>
        /// Возвращает просегментированную цепь
        /// </summary>
        /// <returns></returns>
        public string GetSlotChain()
        {
            return SlotChain.ToString();
        }

        /// <summary>
        /// Возвращает строй просегментированной цепи
        /// </summary>
        /// <returns></returns>
        public string GetFormationSlotChain()
        {
            return ConvertArray.ArrayToString(SlotChain.Building);
        }

        /// <summary>
        /// Возвращает найденый порог
        /// </summary>
        /// <returns></returns>
        public double GetThreshold()
        {
            return Threshold;
        }





    }
}
